home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / cug103 / edit.c < prev    next >
Text File  |  1985-03-10  |  21KB  |  1,033 lines

  1.  
  2. /*    Hello!  This program is supposed to be an editor...  in fact, the
  3.     editor just like mom used to make (oops...) I mean, just like the
  4.     QED editor found most anywhere, especially on UNIX
  5. */
  6.  
  7. #include "edit.inc"
  8.  
  9. main(argc,argv)
  10.     int argc;
  11.     char **argv;
  12.     {
  13.     char *exp_string;
  14.     int i;
  15.     init_buffer();
  16.     prompt_enabled = DEF_PROMPT;
  17.     sprintf(deflt_file,"DEFAULT.$$$");
  18.     print_line_number = DEFAULT_PRINT_LINE_NUMBER;
  19.     exp_string = "+-0123456789.$/?";
  20.     modified_file = NO;
  21.     printer_echo = NO;
  22.     push_point = 0;
  23.     user_command = NO;
  24.     user_string[0] = EOL;
  25.     printf("version 12.9999b by scott fluhrer and neal somos");
  26.     putchar('\n');    /* to force local version in */
  27.     if (argc>1)
  28.         if (argc==2)
  29.             {
  30.             read_file(argv[1]);
  31.             }
  32.         else
  33.             syntax_error();
  34.     for (;;)
  35.         {
  36.         if (user_command)
  37.             {
  38.             for (i=0; line[i] = user_string[i]; i++)
  39.                 ;
  40.             user_command = NO;
  41.             }
  42.         else
  43.             {
  44.             tline[0]='\0';
  45.             if (prompt_enabled)
  46.                 {
  47.                 if (print_line_number)
  48.                     sprintf(tline,"%d>",dot);
  49.                 else    sprintf(tline,">");
  50.                 }
  51.             get_line(line,tline);
  52.             }
  53.         parse = 0;
  54.         skip_space(&parse, line);
  55.         if (char_in_string(line[parse], exp_string))
  56.             {
  57.             number1 = eval_exp(&parse, line);
  58.             if (number1 == ERROR)
  59.                 SYNTAX_ERROR;
  60.             skip_space(&parse, line);
  61.             if (line[parse] == COMMA)
  62.                 {
  63.                 parse++;
  64.                 number2 = eval_exp(&parse, line);
  65.                 if (number2 == ERROR)
  66.                     SYNTAX_ERROR;
  67.                 num_num = 2;
  68.                 }
  69.             else
  70.                 num_num = 1;
  71.             }
  72.         else
  73.             num_num = 0;
  74.         skip_space(&parse, line);
  75.         global = NO;
  76.         found_line = NO;
  77.         if (do_command())
  78.             continue;
  79. oops:        syntax_error();
  80.         }
  81.     }
  82.  
  83. /*    This is the general command do-er, returning YES if everything
  84.     went Hunky-Dory
  85. */
  86. BOOL do_command()
  87.     {
  88.     int l, start_search, i;
  89.     BOOL interact, forced, delete_after_store, print_control;
  90.     char file[MAX_LINE], replace[MAX_LINE+2], *h;
  91.     char *w;
  92.     char string1[MAX_LINE+1], string2[MAX_LINE+1];
  93.     switch( tolower( line[parse] ))
  94.         {
  95.         case 'p':
  96.             print_control = NO;
  97. random_label:        if (check_2_param())
  98.                 return(NO);
  99.             while(l=get_next_line())
  100.                 {
  101.                 print(l, print_control);
  102.                 dot = l;
  103.                 }
  104.             break;
  105.         case 'l':
  106.             print_control = YES;
  107.             goto random_label;
  108.         case EOL:
  109.             if (check_blank())
  110.                 return(NO);
  111.             while (l=get_next_line())
  112.                 {
  113.                 print(l, NO);
  114.                 dot = l;
  115.                 }
  116.             break;
  117.         case 'i':
  118.             if (check_1_param())
  119.                 return(NO);
  120.             if (number1 == 0)
  121.                 return(NO);
  122.             insert(number1);
  123.             break;
  124.         case 'a':
  125.             if (tolower( line[parse+1] ) == 'c')
  126.                 {
  127.                 parse++;
  128.                 if (check_2_param())
  129.                     return(NO);
  130.                 while (l=get_next_line())
  131.                     append_comment(l);
  132.                 break;
  133.                 }
  134.             if (check_1_param())
  135.                 return(NO);
  136.             if (number1 > dollar)
  137.                 return(NO);
  138.             insert(number1+1);
  139.             break;
  140.         case 'd':
  141.             if (check_2_param())
  142.                 return(NO);
  143.             while(l=get_next_line())
  144.                 delete(l);
  145.             break;
  146.         case 'c':
  147.             if (check_2_param())
  148.                 return(NO);
  149.             if (global)
  150.                 return(NO);
  151.             while (l=get_next_line())
  152.                 delete(l);
  153.             insert(number1);
  154.             break;
  155.         case 'm':
  156.             delete_after_store = YES;
  157. move_label:        if (check_3_param())
  158.                 return(NO);
  159.             stuffed_file = NO;
  160.             t = temp_buff;
  161.             while (l=get_next_line())
  162.                 {
  163.                 read_line(l, replace);
  164.                 if (delete_after_store)
  165.                     delete_line(l);
  166.                 for (w=replace; *w; w++)
  167.                     if (save_in_buff(*w))
  168.                         return (NO);
  169.                 if (save_in_buff(EOL))
  170.                     return (NO);
  171.                 }
  172.             if (stuffed_file)
  173.                 seek(fd, 0, 0);
  174.             u = 0;
  175.             while (recall_from_buff(replace))
  176.                 {
  177.                 insert_line(number3, replace);
  178.                 }
  179.             break;
  180.         case 't':
  181.             delete_after_store = NO;
  182.             goto move_label;
  183.         case 'h':
  184.             if (check_0_param())
  185.                 return(NO);
  186.             if ((fd=open("edit.hlp", 0)) == ERROR)
  187.                 return(NO);
  188.             read(fd, temp_buff, 8);
  189.             close(fd);
  190.             for (h=&temp_buff; *h!=CNTRL_Z; h++)
  191.                 printf("%c",*h);
  192.             break;
  193.         case 'u':
  194.             if (line[parse+1] == '=')
  195.                 {
  196.                 if (check_user())
  197.                     return(NO);
  198.                 parse += 2;
  199.                 if (line[parse] == EOL)
  200.                     {
  201.                     printf("%s\n", user_string);
  202.                     break;
  203.                     }
  204.                 for (i=0; line[parse];)
  205.                     user_string[i++] = line[parse++];
  206.                 user_string[i] = EOL;
  207.                 break;
  208.                 }
  209.             if (check_0_param())
  210.                 return(NO);
  211.             user_command = YES;
  212.             break;
  213.         case 'j':
  214.             if (check_1_param())
  215.                 return(NO);
  216.             if (number1==0 OR number1==dollar)
  217.                 return(NO);
  218.             read_line(number1, string1);
  219.             read_line(number1+1, string2);
  220.             if (strlen(string1) + strlen(string2) > MAX_LINE)
  221.                 {
  222.                 printf("Line too long\007\n");
  223.                 return(YES);
  224.                 }
  225.             strcat(string1, string2);
  226.             delete_line(number1+1);
  227.             delete_line(number1);
  228.             insert_line(number1+1, string1);
  229.             dot = number1+1;
  230.             break;
  231.         case 'n':
  232.             if (check_file(file))
  233.                 return(NO);
  234.             if (push_point == MAX_FILES)
  235.                 return(NO);
  236.             if (fopen(file, &iobuf[push_point]) == ERROR)
  237.                 return(NO);
  238.             push_point++;
  239.             break;
  240.         case 'r':
  241.             if (check_file(file))
  242.                 return(NO);
  243.             read_file(file);
  244.             break;
  245.         case 'w':
  246.             if (check_file(file))
  247.                 return(NO);
  248.             write_file(file);
  249.             break;
  250.         case 'f':
  251.             if (line[parse+1] == '=')
  252.                 {
  253.                 parse++;
  254.                 if (check_file(file))
  255.                     return(NO);
  256.                 strcpy(deflt_file, file);
  257.                 break;
  258.                 }
  259.             if (strcmp(deflt_file, "") == 0)
  260.                 printf("\007??\n");
  261.             else
  262.                 printf("%s\n", deflt_file);
  263.             break;
  264.         case '#':
  265.             if (check_0_param())
  266.                 return(NO);
  267.             print_line_number ^= YES;
  268.             break;
  269.         case '>':
  270.             if (check_0_param())
  271.                 return(NO);
  272.             prompt_enabled = NO;
  273.             break;
  274.         case '<':
  275.             if (check_0_param())
  276.                 return(NO);
  277.             prompt_enabled = YES;
  278.             break;
  279.         case 'q':
  280.             if (line[parse+1] == '!')
  281.                 {
  282.                 parse++;
  283.                 forced = YES;
  284.                 }
  285.             else
  286.                 forced = NO;
  287.             if (check_0_param())
  288.                 return(NO);
  289.             if (modified_file AND NOT forced)
  290.                 {
  291.                 printf("Write??\007\n");
  292.                 modified_file = NO;
  293.                 break;
  294.                 }
  295.             else
  296.                 {
  297.                 if (temp_used)
  298.                     unlink(TEMP_FILE);
  299.                 exit(YES);
  300.                 }
  301.         case 's':
  302.             interact = NO;
  303. search_label:        if (check_search())
  304.                 return(NO);
  305.             if (NOT global)
  306.                 init_search();
  307.             start_search = place_search(&parse, line);
  308.             if (start_search == ERROR)
  309.                 return(NO);
  310.             if (NOT get_replace(&parse, line, replace))
  311.                 return(NO);
  312.             g_mode = p_mode = NO;
  313.             if (NOT get_options())
  314.                 return(NO);
  315.             if (interact)
  316.                 {
  317.                 if (g_mode)
  318.                     return(NO);
  319.                 g_mode = YES;
  320.                 }
  321.             while (l=get_next_line())
  322.                 substitute(l, start_search, replace, interact);
  323.             break;
  324.         case 'x':
  325.             interact = YES;
  326.             goto search_label;
  327.         case 'g':
  328.             search_true = YES;
  329. global_search:        if (check_global())
  330.                 return(NO);
  331.             global = YES;
  332.             init_search();
  333.             if (place_search(&parse, line) == ERROR)
  334.                 return(NO);
  335.             return(do_command());
  336.         case 'v':
  337.             search_true = NO;
  338.             goto global_search;
  339.         case '=':
  340.             if (check_1_param())
  341.                 return(NO);
  342.             printf("%d\n", number1);
  343.             break;
  344.         case '%':
  345.             if (check_1_param())
  346.                 return(NO);
  347.             if (dollar == 0 OR number1 == 0 OR number1>dollar)
  348.                 return(NO);
  349.             dot = number1;
  350.             for (i=max(1, dot-8); i<dot; i++)
  351.                 print(i, NO);
  352.             HIGH_LIGHT;
  353.             print(dot, NO);
  354.             STOP_HIGH_LIGHT;
  355.             for (i=dot+1;i<=min(dot+8, dollar); i++)
  356.                 print(i, NO);
  357.             break;
  358.         case ':':
  359.             if (check_1_param())
  360.                 return(NO);
  361.             if (number1 > dollar OR number1 == 0)
  362.                 return(NO);
  363.             dot = number1;
  364.             for (i=dot; i<=min(dot+16, dollar); i++)
  365.                 print(i, NO);
  366.             break;
  367.         case '^':
  368.             if (check_1_param())
  369.                 return(NO);
  370.             if (dot == 0)
  371.                 return(NO);
  372.             for (;;)
  373.                 {
  374.                 if (kbhit())
  375.                     {
  376.                     getchar();
  377.                     printf("!\007    %d\n", dot);
  378.                     break;
  379.                     }
  380.                 print(dot, NO);
  381.                 if (dot == dollar)
  382.                     break;
  383.                 dot++;
  384.                 }
  385.             break;
  386.         case '&':
  387.             if (check_1_param())
  388.                 return(NO);
  389.             if (number1 > dollar)
  390.                 return(NO);
  391.             dot = number1;
  392.             for (i=max(dot-16, 1); i<=dot; i++)
  393.                 print(i, NO);
  394.             break;
  395.         case QUOTE:
  396.             if (check_1_param())
  397.                 return(NO);
  398.             if (number1>dollar)
  399.                 return(NO);
  400.             for (i=min(number1+1, dollar); i<=min(number1+17,
  401.                 dollar); i++)
  402.                 {
  403.                 dot = i;
  404.                 print(i, NO);
  405.                 }
  406.             break;
  407.         case '~':
  408.             if (check_1_param())
  409.                 return(NO);
  410.             if (number1>dollar)
  411.                 return(NO);
  412.             for (i = dot = max(1, number1-17); i<=number1; i++)
  413.                 print(i, NO);
  414.             break;
  415.         case '!':
  416.             for (i=0; parsels[i].type!=EOF; i++)
  417.                 {
  418.                 printf("%d", i);
  419.                 if (parsels[i].type == IN_MEM)
  420.                     printf("-in memory   ");
  421.                 else if (parsels[i].type == IN_TEMP_FILE)
  422.                     printf("-in temp file");
  423.                 else
  424.                     printf("-Illegal type");
  425.                 printf(" at %d", parsels[i].where);
  426.                 printf(" line number %d\n", parsels[i].line_no);
  427.                 }
  428.             for (i=0; i<NO_MEMORIES; i++)
  429.                 if (memory[i].used)
  430.                     {
  431.                     printf("%d-being used by parsel ", i);
  432.                     printf("%d-lru = %d\n", memory[i].parsel_no, memory[i].lru);
  433.                     }
  434.                 else
  435.                     printf("%d-Not being used\n", i);
  436.             break;
  437.         case '@':
  438.             printf("Kathy, don't do that, it tickles\n");
  439.             break;
  440.         case '*':
  441.             printf("Now Kathy, stop fooling around\n");
  442.             break;
  443.         default:
  444.             return(NO);
  445.         }
  446.     return(YES);
  447.     }
  448.  
  449. int max(a,b)
  450.     int a,b;
  451.     {
  452.     return(a>b?a:b);
  453.     }
  454.  
  455. int min(a,b)
  456.     int a,b;
  457.     {
  458.     return(a<b?a:b);
  459.     }
  460.  
  461. /*    This is the character storer */
  462. BOOL save_in_buff(n)
  463.     char n;
  464.     {
  465.     *t++ = n;
  466.     if (t == (temp_buff+BUFF_SIZE))
  467.         {
  468.         if (NOT stuffed_file)
  469.             {
  470.             fd = creat(MOVE_FILE);
  471.             if (fd == ERROR)
  472.                 return(YES);
  473.             close(fd);
  474.             fd = open(MOVE_FILE, 2);
  475.             if (fd == ERROR)
  476.                 return(YES);
  477.             }
  478.         stuffed_file++;
  479.         if (write(fd, temp_buff, BUFF_SIZE/CPM_SIZE) != BUFF_SIZE/CPM_SIZE)
  480.             {
  481.             close(fd);
  482.             unlink(MOVE_FILE);
  483.             return(YES);
  484.             }
  485.         t = temp_buff;
  486.         }
  487.     return(NO);
  488.     }
  489.  
  490. /*    This is the line recaller */
  491. BOOL recall_from_buff(line)
  492.     char *line;
  493.     {
  494.     if (stuffed_file==0 AND u+temp_buff==t)
  495.         return(NO);
  496.     while (*line++ = recall_char())
  497.         ;
  498.     return(YES);
  499.     }
  500.  
  501. char recall_char()
  502.     {
  503.     char c;
  504.     char *testptr;
  505.     if (u==0 AND stuffed_file)
  506.         read(fd, temp2_buff, BUFF_SIZE/CPM_SIZE);
  507.     c = (stuffed_file?temp2_buff:temp_buff)[u++];
  508.     if (u == BUFF_SIZE)
  509.         {
  510.         stuffed_file--;
  511.         u = 0;
  512.         if (stuffed_file == 0)
  513.             {
  514.             close(fd);
  515.             unlink(MOVE_FILE);
  516.             }
  517.         }
  518.     return(c);
  519.     }
  520.  
  521. /*    This is the great and wonderfull (well, almost wonderful) line input
  522.     routine.  It will input a line anywhere (well, anywhere you give
  523.     a pointer to) and it will enter up to MAX_LINE characters, beeping
  524.     incessently if the user tries to enter more.  It also handles delete
  525.     in a half-way intelligent manner.
  526. */
  527. get_line(line,from)
  528.     char *from;
  529.     char *line;
  530.     {
  531.     int position;
  532.     int loc;
  533.     char character;
  534.     position = 0;
  535.     loc=0;
  536.     if (*from!=0) printf("%s",from);
  537.     for (;;)
  538.         {
  539.         if (push_point == 0)
  540.             {
  541.             character = getchar();
  542.             if (printer_echo) bdos(5,character);
  543.             }
  544.         else
  545.             {
  546.             character = ubgetc(&iobuf[push_point-1]);
  547.             if (character != CNTRL_Z)
  548.                 printf("%c", character);
  549.             }
  550.         switch(character)
  551.             {
  552.             case CNTRL_Z:
  553.                 if (push_point == 0)
  554.                     {
  555.                     printf("\007");
  556.                     break;
  557.                     }
  558.                 fclose(&iobuf[--push_point]);
  559.                 break;
  560.             case LF:
  561.                 line[position] = EOL;
  562.                 return;
  563.             case DELETE:
  564.             case BS:
  565.                 if (position == 0)
  566.                     {
  567.                     printf("\007");
  568.                     break;
  569.                     }
  570.                 position--;
  571.                 if (line[position] == TAB)
  572.                     {
  573.                     line[position] = EOL;
  574.                     printline(line,from);
  575.                     }
  576.                 else
  577.                     {
  578.                     printf("\010 \010");
  579.             printf(" \010 \010 \010 \010 \010 \010");
  580.                     line[position] = EOL;
  581.                     }
  582.                 break;
  583.             case CNTRL_X:
  584.                 position = 0;
  585.                 printf("\\\n");
  586.                 printline("", from);
  587.                 break;
  588.             case CNTRL_P:
  589.                 printer_echo=!printer_echo;
  590.                 break;
  591.             case CNTRL_R:
  592.                 line[position] = EOL;
  593.                 printline(line,from);
  594.                 break;
  595.             case TAB:
  596.                 goto skip_check;
  597.             default:
  598.                 if (character<SPACE OR character>DELETE)
  599.                     {
  600.                     printf("\007");
  601.                     break;
  602.                     }
  603. skip_check:            if (position == MAX_LINE)
  604.                     {
  605.                     printf("\007");
  606.                     if (character == TAB)
  607.                         {
  608.                         line[position] = EOL;
  609.                         printline(line,from);
  610.                         }
  611.                     else
  612.                         printf("\010 \010");
  613.                     break;
  614.                     }
  615.                 line[position++] = character;
  616.             }
  617.         }
  618.     }
  619.  
  620. /* print_line */
  621. printline(line,from)
  622. char *from;
  623. char *line;
  624. {
  625. printf("\n");
  626. if (*from!=0) printf("%s",from);
  627. if (*line!=0) printf("%s",line);
  628. }
  629.  
  630. /*    This is the main syntax error complainer */
  631. syntax_error()
  632.     {
  633.     printf("?\007\n");
  634.     }
  635.  
  636. /*    This function will check if the character given lines in the string */
  637. BOOL char_in_string(character, string)
  638.     char character, *string;
  639.     {
  640.     while (*string)
  641.         if (*string++ == character)
  642.             return(YES);
  643.     return(NO);
  644.     }
  645.  
  646. /*    This function will skip any white space (spaces or tabs) in the line
  647.     given to it */
  648. skip_space(pointer, line)
  649.     int *pointer;
  650.     char line[];
  651.     {
  652.     while (line[*pointer] == SPACE OR line[*pointer] == TAB)
  653.         ++*pointer;
  654.     }
  655.  
  656. /*    This is the wonderful, marvulous(sick(sic)), amazing expression
  657.     evaluator.  An expression is something that specifies a line nuMBER,
  658.     2, 35, +, $, .+3, /abc/, ?x.y?-2, /^*.$/, you get the picture.
  659. */
  660. int eval_exp(count, line)
  661.     int *count;
  662.     char line[];
  663. #define NOP 0
  664. #define ADD 1
  665. #define SUB 2
  666. #define INC 3
  667. #define DEC 4
  668.     {
  669.     BOOL operator_expected;
  670.     FLAG oper_seen;
  671.     int defalut, number;
  672.     operator_expected = NO;
  673.     oper_seen = NOP;
  674.     defalut = dot;
  675.     for (;;)
  676.         {
  677.         skip_space(count, line);
  678.         switch (line[*count])
  679.             {
  680.             case '0': case '1': case '2':
  681.             case '3': case '4': case '5':
  682.             case '6': case '7': case '8':
  683.             case '9':
  684.                 number = 0;
  685.                 while (isdigit(line[*count]))
  686.                     number = 10*number + (line[(*count)++] - '0');
  687. got_number:            if (operator_expected)
  688.                     return(ERROR);
  689.                 if (oper_seen == NOP)
  690.                     defalut = number;
  691.                 else if (oper_seen == ADD OR oper_seen == INC)
  692.                     defalut += number;
  693.                 else
  694.                     defalut -= number;
  695.                 operator_expected = YES;
  696.                 break;
  697.             case '$':
  698.                 number = dollar;
  699.                 ++*count;
  700.                 goto got_number;
  701.             case '.':
  702.                 number = dot;
  703.                 ++*count;
  704.                 goto got_number;
  705.             case '/':
  706.                 init_search();
  707.                 if (place_search(count, line) == ERROR)
  708.                     return(NO);
  709.                 number = find_line(dot+1, YES);
  710. check_search:            if (number == 0)
  711.                     {
  712.                     printf("?");
  713.                     return(NO);
  714.                     }
  715.                 goto got_number;
  716.             case '?':
  717.                 init_search();
  718.                 if (place_search(count, line) == ERROR)
  719.                     return(NO);
  720.                 number = find_line(dot-1, NO);
  721.                 goto check_search;
  722.             case '+':
  723.                 ++*count;
  724.                 if (operator_expected)
  725.                     {
  726.                     oper_seen = ADD;
  727.                     operator_expected = NO;
  728.                     break;
  729.                     }
  730.                 if (oper_seen == INC)
  731.                     {
  732.                     defalut++;
  733.                     break;
  734.                     }
  735.                 if (oper_seen == NOP)
  736.                     {
  737.                     oper_seen = INC;
  738.                     break;
  739.                     }
  740.                 return(ERROR);
  741.             case '-':
  742.                 ++*count;
  743.                 if (operator_expected)
  744.                     {
  745.                     oper_seen = SUB;
  746.                     operator_expected = NO;
  747.                     break;
  748.                     }
  749.                 if (oper_seen == DEC)
  750.                     {
  751.                     defalut--;
  752.                     break;
  753.                     }
  754.                 if (oper_seen == NOP)
  755.                     {
  756.                     oper_seen = DEC;
  757.                     break;
  758.                     }
  759.                 return(ERROR);
  760.             default:
  761.                 if (operator_expected)
  762.                     return(defalut);
  763.                 if (oper_seen == INC)
  764.                     return(defalut+1);
  765.                 if (oper_seen == DEC)
  766.                     return(defalut-1);
  767.                 return(ERROR);
  768.             }
  769.         }
  770.     }
  771.  
  772. /*    This procedure will check if a command with up to 2 parameters is
  773.     expressed properly.  If not, it will return YES.  If it is, this will
  774.     alter number1 and number2 to deflt values when there are less than
  775.     2 values.
  776. */
  777. BOOL check_2_param()
  778.     {
  779.     parse++;
  780.     skip_space(&parse, line);
  781.     if (line[parse] != EOL)
  782.         return(YES);
  783.     if (global)
  784.         return(NO);
  785.     if (num_num == 0)
  786.         number1 = dot;
  787.     if (num_num < 2)
  788.         number2 = number1;
  789.     if (number2>dollar OR number1<1 OR number2<number1)
  790.         return(YES);
  791.     return(NO);
  792.     }
  793.  
  794. BOOL check_3_param()
  795.     {
  796.     parse++;
  797.     number3 = eval_exp(&parse, line);
  798.     if (number3 == ERROR)
  799.         return(YES);
  800.     if (number3<1 OR number3>dollar+1)
  801.         return(YES);
  802.     skip_space(&parse, line);
  803.     if (line[parse] != EOL)
  804.         return(YES);
  805.     if (global)
  806.         return(NO);
  807.     if (num_num == 0)
  808.         number1 = dot;
  809.     if (num_num < 2)
  810.         number2 = number1;
  811.     if (number2>dollar+1 OR number1<1 OR number2<number1)
  812.         return(YES);
  813.     return(NO);
  814.     }
  815. BOOL check_user()
  816.     {
  817.     if (global)
  818.         return(YES);
  819.     if (num_num != 0)
  820.         return(YES);
  821.     return(NO);
  822.     }
  823. BOOL check_search()
  824.     {
  825.     parse++;
  826.     if (global)
  827.         return(NO);
  828.     if (num_num == 0)
  829.         number1 = dot;
  830.     if (num_num < 2)
  831.         number2 = number1;
  832.     if (number2>dollar OR number1<1 OR number2<number1)
  833.         return(YES);
  834.     return(NO);
  835.     }
  836.  
  837. /*    This will do about the same thing, but for the null command */
  838. BOOL check_blank()
  839.     {
  840.     if (global)
  841.         return(NO);
  842.     if (num_num == 0)
  843.         number1 = dot + 1;
  844.     if (num_num < 2)
  845.         number2 = number1;
  846.     if (number2>dollar OR number1<1 OR number2<number1)
  847.         return(YES);
  848.     return(NO);
  849.     }
  850.  
  851. /*    This will do just about the same thing, but with only 1 parameter
  852. */
  853. BOOL check_1_param()
  854.     {
  855.     parse++;
  856.     skip_space(&parse, line);
  857.     if (line[parse] != EOL)
  858.         return(YES);
  859.     if (global)
  860.         return(YES);
  861.     if (num_num == 0)
  862.         number1 = dot;
  863.     if (num_num == 2)
  864.         return(YES);
  865.     if (number1<0 OR number1>dollar+1)
  866.         return(YES);
  867.     return(NO);
  868.     }
  869.  
  870. /*    This will do the same thing, but without any parameters */
  871. BOOL check_0_param()
  872.     {
  873.     parse++;
  874.     skip_space(&parse, line);
  875.     if (line[parse] != EOL)
  876.         return(YES);
  877.     if (global)
  878.         return(YES);
  879.     if (num_num != 0)
  880.         return(YES);
  881.     return(NO);
  882.     }
  883.  
  884. /*    This will do the same thing, but with a file name at the end */
  885. BOOL check_file(file_name)
  886.     char file_name[];
  887.     {
  888.     parse++;
  889.     if (global)
  890.         return(YES);
  891.     if (num_num != 0)
  892.         return(YES);
  893.     skip_space(&parse, line);
  894.     if (line[parse] == EOL)
  895.         if (deflt_file[0] == EOL)
  896.             return(YES);
  897.         else
  898.             strcpy(file_name, deflt_file);
  899.     else
  900.         strcpy(file_name, line + parse);
  901.     return(NO);
  902.     }
  903.  
  904. /*    This will check a global command */
  905. check_global()
  906.     {
  907.     parse++;
  908.     if (global)
  909.         return(YES);
  910.     if (num_num == 0)
  911.         {
  912.         number1 = 1;
  913.         number2 = dollar;
  914.         if (dollar < 1)
  915.             return(YES);
  916.         }
  917.     if (num_num == 1)
  918.         number2 = number1;
  919.     if (number1 < 1 OR number2 > dollar OR number1 > number2)
  920.         return(YES);
  921.     return(NO);
  922.     }
  923.  
  924. /*    This will get the next line (if any) */
  925. int get_next_line()
  926.     {
  927.     while (global AND number1<=number2 AND NOT kbhit() AND
  928.         (search_true XOR test_line(number1)))
  929.         number1++;
  930.     if (kbhit())
  931.         {
  932.         getchar();
  933.         printf("!\007  %d\n",number1);
  934.         return(NO);
  935.         }
  936.     if (number1 > number2)
  937.         {
  938.         if (NOT found_line)
  939.             printf("??\007\n");
  940.         return(NO);
  941.         }
  942.     found_line = YES;
  943.     return(number1++);
  944.     }
  945.  
  946. /*    This procedure will print a whole bunch of lines */
  947. print(this, print_control)
  948.     int this;
  949.     BOOL print_control;
  950.     {
  951.     char line[MAX_LINE+2];
  952.     int i;
  953.     read_line(this, line);
  954.     if (print_line_number)
  955.         printf("%d\t", this);
  956.     if (print_control)
  957.         {
  958.         for (i=0; line[i]; i++)
  959.             if (line[i]<32)
  960.                 printf("^%c", line[i]+'@');
  961.             else if (line[i]>127)
  962.                 printf("@%c", line[i] & 0x7f);
  963.             else printf("%c", line[i]);
  964.         printf("\n");
  965.         }
  966.     else
  967.         printf("%s\n", line);
  968.     }
  969.  
  970. /*    This procedure will delete a whole bunch of lines */
  971. delete(this)
  972.     int this;
  973.     {
  974.     delete_line(this);
  975.     if (dollar<this)
  976.         dot = dollar;
  977.     else
  978.         dot = this;
  979.     }
  980.  
  981. /*    This procedure will insert a whole bunch of lines */
  982. insert(from)
  983.     int from;
  984.     {
  985.     char line[MAX_LINE+2];
  986.     for (;;)
  987.         {
  988.         if (print_line_number)
  989.             sprintf(tline,"%-8.8d",from);
  990.         else    tline[0]='\0';
  991.         get_line(line,tline);
  992.         if (strcmp(line, ".") == 0)
  993.             return;
  994.         dot = from;
  995.         insert_line(from++, line);
  996.         }
  997.     }
  998.  
  999. /*    This will do the appending of comments */
  1000. append_comment(l)
  1001.     int l;
  1002.     {
  1003.     char line[MAX_LINE+1], comments[MAX_LINE+1];
  1004.     read_line(l, line);
  1005.     sprintf(tline,"%s\t/\* ", line);
  1006.     get_line(comments,tline);
  1007.     if (NOT *comments)
  1008.         return;
  1009.     if (strlen(line)+strlen(comments)+7 > MAX_LINE)
  1010.         {
  1011.         printf("Line too long\007\n");
  1012.         return;
  1013.         }
  1014.     strcat(line, "\t/\* ");
  1015.     strcat(line, comments);
  1016.     strcat(line, " */");
  1017.     delete_line(l);
  1018.     insert_line(l, line);
  1019.     }
  1020. /* local version of putchar to not interrogate console */
  1021. putchar(c)
  1022. char c;
  1023. {
  1024. putch(c);
  1025. if (printer_echo)
  1026.     bdos(5,c);
  1027. }
  1028. /* thats it */
  1029. f putchar to not interrogate console */
  1030. putchar(c)
  1031. char c;
  1032. {
  1033. putch(c);